package com.polaris.live.utils

import android.app.Activity
import android.content.Context
import android.os.Bundle
import com.blankj.utilcode.util.StringUtils
import com.hjq.language.MultiLanguages
import com.polaris.live.common.appContext
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.constant.AppConst
import com.polaris.live.common.constant.CacheConst
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.common.mvvm.viewmodel.BaseViewModel
import com.polaris.live.common.network.requestLoading
import com.polaris.live.common.util.ReflexUtils
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.common.util.ViewUtils
import com.polaris.live.constant.LiveConst
import com.polaris.live.constant.LiveConst.LivePage
import com.polaris.live.im.sfs.bean.live.CallSignalingMessage
import com.polaris.live.im.sfs.bean.live.LiveRoomInfo
import com.polaris.live.im.sfs.bean.live.ext.UserBasicVo
import com.polaris.live.im.sfs.bean.live.toUserBasic
import com.polaris.live.net.liveService
import com.polaris.live.popup.GlobalPopupManager
import com.polaris.live.resp.back_resp.CallStartResp
import com.polaris.live.resp.back_resp.DisplayUserBean
import com.polaris.live.resp.back_resp.InfoOtherResp
import com.polaris.live.resp.back_resp.ScreenshotStrategyVo
import com.polaris.live.resp.back_resp.toUserBasicVo
import com.polaris.live.translation.R
import com.polaris.live.utils.CommonUtils.toBoolean
import com.polaris.live.utils.route.RoutePath
import com.polaris.live.utils.route.Router
import com.tencent.mmkv.MMKV
import kotlinx.coroutines.launch
import sfs2x.client.entities.variables.RoomVariable
import kotlin.reflect.KMutableProperty
import kotlin.reflect.full.isSubtypeOf
import kotlin.reflect.full.memberProperties
import kotlin.reflect.full.starProjectedType
import kotlin.reflect.full.withNullability

/**
 * LiveUtils
 *
 * @author Created by lucas on 2023/11/9 11:29
 */
object LiveUtils {

    /**
     * 跳转到观众的直播间
     */
    fun toSpectator(item: DisplayUserBean, childRouter: String? = null): LiveSpectatorBuilder {
        return toSpectator(item.base.userId)
            .witchStreamId(item.playStreamId)
            .withCover(item.cover)
            .withUser(item.base)
            .withChildRouter(childRouter)
    }

    /**
     * 跳转到观众的直播间
     */
    fun toSpectator(info: InfoOtherResp, childRouter: String? = null): LiveSpectatorBuilder {
        return toSpectator(info.userId)
            .witchStreamId(info.live?.liveStreamId)
            .withCover(info.coverPhoto?.url)
            .withChildRouter(childRouter)
            .withUser(info.toUserBasicVo())
    }

    /**
     * 跳转到观众的直播间
     */
    fun toSpectator(anchorId: Long): LiveSpectatorBuilder {
        return LiveSpectatorBuilder(anchorId)
    }

    class LiveSpectatorBuilder(anchorId: Long) {

        private val router = Router.builder(RoutePath.LIVE_SPECTATOR_ACTIVITY)
            .withLong("anchorId", anchorId)

        fun witchStreamId(streamId: String?): LiveSpectatorBuilder {
            router.withStringNullable("streamId", streamId)
            return this
        }

        fun withCover(cover: String?): LiveSpectatorBuilder {
            router.withStringNullable("cover", cover)
            return this
        }

        fun withUser(user: UserBasicVo?): LiveSpectatorBuilder {
            router.withAnyNullable("user", user)
            return this
        }

        fun withGame(isGame: Boolean): LiveSpectatorBuilder {
            router.withBoolean("isGame", isGame)
            return this
        }

        fun withChildRouter(childRouter: String? = null): LiveSpectatorBuilder {
            if (childRouter != null) {
                router.withString("router", childRouter)
            }
            return this
        }

        fun navigation(activity: Activity) {
            router.navigation(activity)
        }

        fun navigation(context: Context) {
            router.navigation(context)
        }

        fun navigation(context: Context, options: Bundle?) {
            router.navigation(context, options)
        }
    }

    /**
     * 格式化为时间
     */
    fun formatTime(elapsedTime: Long): String {
        val seconds = (elapsedTime / 1000 % 60).toInt()
        val minutes = (elapsedTime / 1000 / 60).toInt()
        return String.format(
            MultiLanguages.getSystemLanguage(appContext),
            "%02d:%02d",
            minutes,
            seconds
        )
    }

    /**
     * 获取通话的对方用户
     */
    fun getCallOtherUser(
        callBean: CallStartResp?,
        callMessage: CallSignalingMessage?,
        otherUser: UserBasicVo? = null,
    ): UserBasicVo? {
        val answer = callBean?.answer
        return if (answer != null && answer.userId != UserManager.getUserId()) {
            answer
        } else {
            callMessage?.toUserBasic() ?: otherUser
        }
    }

    /**
     * 填充单个数据
     */
    fun fillLiveInfo(liveInfo: LiveRoomInfo, variable: RoomVariable) {
        liveRoomInfoMemberProperties[variable.name]?.also { property ->
            if (property is KMutableProperty<*>) {
                val returnType = property.returnType
                val value = variable.value
                if (value == null) {
                    if (returnType.isMarkedNullable) {
                        property.setter.call(liveInfo, null)
                    }
                } else {
                    val starProjectedType = value::class.starProjectedType
                    if (!returnType.isMarkedNullable && returnType.isSubtypeOf(starProjectedType)
                        || returnType.isMarkedNullable && returnType.isSubtypeOf(
                            starProjectedType.withNullability(
                                true
                            )
                        )
                    ) {
                        property.setter.call(liveInfo, value)
                    } else {
                        ReflexUtils.convertNumber(value, returnType)?.also {
                            property.setter.call(liveInfo, it)
                        }
                    }
                }
            }
        }
    }

    private val liveRoomInfoMemberProperties =
        LiveRoomInfo::class.memberProperties.associateBy { it.name }

    private val screenshotStrategyMap = HashSet<String>()

    /**
     * 处理截图策略
     *
     * 如果不为空则先存储，否则取出缓存
     */
    fun resolveScreenshotStrategy(
        @LivePage pageType: Int,
        vo: ScreenshotStrategyVo?,
    ): ScreenshotStrategyVo? {
        val key = "${pageType}ScreenshotStrategy"

        if (vo == null) {
            val kv = MMKV.mmkvWithID(CacheConst.TEMP)
            return kv.decodeParcelable(key, ScreenshotStrategyVo::class.java)
        }

        if (screenshotStrategyMap.add(key)) {
            CoroutineScopeManager.defaultScope.launch {
                val kv = MMKV.mmkvWithID(CacheConst.TEMP)
                kv.encode(key, vo)
            }
        }

        return vo
    }

    /**
     * 直播 派对 游戏转跳
     */
    fun invokeSpectator(
        context: Context,
        base: DisplayUserBean,
        childRouter: String? = null,
        needGoProfile: Boolean = false,
    ) {
        if (base.roomId != null || base.base.living?.toBoolean() == true) {
            when (base.base.liveType) {
                //派对房
                LiveConst.Type.PARTY_LIVE -> {
                    val router = Router.builder(RoutePath.PARTY_SPECTATOR_ACTIVITY)
                        .withInt(LiveConst.Params.LIVETYPE, LiveConst.Type.PARTY_LIVE)
                        .withLong(LiveConst.Params.ANCHORID, base.base.userId)
                        .withString(LiveConst.Params.ROOMID, base.roomId ?: "${base.base.userId}")
                    if (childRouter != null) {
                        router.withString("router", childRouter)
                    }
                    router.navigation(context)
                }
                //VIDEO_PARTY派对房
                LiveConst.Type.VIDEO_PARTY -> {
                    val router = Router.builder(RoutePath.PARTY_SPECTATOR_ACTIVITY)
                        .withInt(LiveConst.Params.LIVETYPE, LiveConst.Type.VIDEO_PARTY)
                        .withLong(LiveConst.Params.ANCHORID, base.base.userId)
                        .withString(LiveConst.Params.ROOMID, base.roomId ?: "${base.base.userId}")
                    if (childRouter != null) {
                        router.withString("router", childRouter)
                    }
                    router.navigation(context)
                }
                //游戏房
                LiveConst.Type.PARTY_GAME_LIVE -> {
                    val router = Router.builder(RoutePath.PARTY_GAME_SPECTATOR_ACTIVITY)
                        .withLong(LiveConst.Params.ANCHORID, base.base.userId)
                        .withString(LiveConst.Params.ROOMID, base.roomId ?: "${base.base.userId}")
                    if (childRouter != null) {
                        router.withString("router", childRouter)
                    }
                    router.navigation(context)
                }


                //仅直播，直播坐等
                LiveConst.Type.ONLY_LIVE, LiveConst.Type.LIVE_AND_MATCH -> {
                    toSpectator(base).navigation(context)
                }
            }
        } else {
            if (needGoProfile) {
                Router.builder(RoutePath.USER_SPACE_ACTIVITY)
                    .withLong("userId", base.base.userId)
                    .withAny("userBasic", base.base)
                    .navigation(context)
            } else {
                ToastGravity.showGravity(StringUtils.getString(R.string.room_end))
            }
        }
    }

    fun invokeSpectator(context: Context, base: InfoOtherResp, needGoProfile: Boolean = false) {
        if (base.live?.roomId != null || base.live?.living == true) {
            when (base.live.liveType) {
                //派对房
                LiveConst.Type.PARTY_LIVE -> {
                    Router.instance.setPath(RoutePath.PARTY_SPECTATOR_ACTIVITY)
                        .withInt(LiveConst.Params.LIVETYPE, LiveConst.Type.PARTY_LIVE)
                        .withLong(LiveConst.Params.ANCHORID, base.userId)
                        .withString(LiveConst.Params.ROOMID, base.live.roomId ?: "")
                        .navigation(context)
                }
                //VIDEO_PARTY派对房
                LiveConst.Type.VIDEO_PARTY -> {
                    Router.instance.setPath(RoutePath.PARTY_SPECTATOR_ACTIVITY)
                        .withInt(LiveConst.Params.LIVETYPE, LiveConst.Type.VIDEO_PARTY)
                        .withLong(LiveConst.Params.ANCHORID, base.userId)
                        .withString(LiveConst.Params.ROOMID, base.live.roomId ?: "")
                        .navigation(context)
                }
                //游戏房
                LiveConst.Type.PARTY_GAME_LIVE -> {
                    Router.instance.setPath(RoutePath.PARTY_GAME_SPECTATOR_ACTIVITY)
                        .withLong(LiveConst.Params.ANCHORID, base.userId)
                        .withString(LiveConst.Params.ROOMID, base.live.roomId ?: "")
                        .navigation(context)
                }
                //仅直播，直播坐等
                LiveConst.Type.ONLY_LIVE, LiveConst.Type.LIVE_AND_MATCH -> {
                    toSpectator(base).navigation(context)
                }
            }
        } else {
            if (needGoProfile) {
                Router.builder(RoutePath.USER_SPACE_ACTIVITY)
                    .withLong("userId", base.userId)
                    .withAny("userBasic", base.toUserBasicVo())
                    .navigation(context)
            } else {
                ToastGravity.showGravity(StringUtils.getString(R.string.room_end))
            }
        }
    }

    /**
     * 开启派对房间检查
     */
    fun openPartyChecking(context: Context, viewModel: BaseViewModel) {
        GlobalPopupManager.showCompletePopup(context, isOk = {
            viewModel.requestLoading({ liveService.getPartyRoom() }, {
                val activity = ViewUtils.getAliveTopCompatActivity() ?: return@requestLoading
                if (it.roomId?.isNotEmpty() == true) {
                    val liveType = UserManager.getUser().live?.liveType
                    StartLiveProxy.builder(activity).recoverLive(viewModel, liveType, it.roomId)
                } else {
                    //开启派对
                    Router.builder(RoutePath.SET_PARTY_COVER_ACTIVITY)
                        .navigation(activity)
                }
            })
        })
    }

    fun isToWaiting(base: DisplayUserBean): Boolean {
        return base.base.living == AppConst.YES && base.base.liveType == LiveConst.Type.ONLY_MATCH
    }
}